# code:utf8
import json
import logging
import math
from datetime import datetime
from pyquery import PyQuery
from zc_core.model.items import OrderItem, Sku, ItemGroup, Catalog, Order
from zc_core.util.batch_gen import time_to_batch_no
from zc_core.util.common import parse_time, parse_timestamp
from zc_core.util.encrypt_util import double_base64_encode, base64_decode, short_uuid, md5
from esgcc.items import EsgccItemData, EsgccCompareGroup, SkuAttr
from esgcc.matcher import *

logger = logging.getLogger('rule')


# 解析catalog列表
def parse_catalog(response):
    jpy = PyQuery(response.text)
    li_list = jpy('ul.categorys_list>li.category_item')

    cats = list()
    for li in li_list.items():
        # 一级分类
        cat1_a = li('div.category_link a').eq(0)
        cat1_name = cat1_a.text().strip()
        # 国网品类编码特定编码方案
        cat1_id = double_base64_encode(cat1_name + ':1')
        cat1 = _build_catalog(cat1_id, cat1_name, '', 1)
        cats.append(cat1)
        # 二级分类
        cat2_dls = li('dl.c_d_main_con')
        for dl in cat2_dls.items():
            cat2_id = ''
            for sub in dl.children().items():
                if sub.has_class('tit'):
                    cat2_name = sub.text().strip()
                    # 国网品类编码特定编码方案
                    cat2_id = double_base64_encode(cat2_name + ':2')
                    cat2 = _build_catalog(cat2_id, cat2_name, cat1_id, 2)
                    cats.append(cat2)
                else:
                    # 三级分类
                    cat3_a = sub('a')
                    url = cat3_a.attr('href')
                    if url:
                        cat3_name = cat3_a.text().strip()
                        cat3_id = match_cat_id(url.strip())
                        cat3 = _build_catalog(cat3_id, cat3_name, cat2_id, 3)
                        cats.append(cat3)

    return cats


def _build_catalog(cat_id, cat_name, parent_id, level):
    cat = Catalog()
    cat['catalogId'] = cat_id
    cat['catalogName'] = cat_name
    cat['parentId'] = parent_id
    cat['level'] = level
    if level == 3:
        cat['leafFlag'] = 1
    else:
        cat['leafFlag'] = 0
    cat['linkable'] = 0

    return cat


# 解析sku列表
def parse_sku_page(response):
    js_str = clean_jsonp(response.text)
    rs = json.loads(js_str)
    if 'maxPage' in rs:
        return rs.get('maxPage', 0)

    return 0


# 解析sku列表
def parse_sku(response):
    meta = response.meta
    sp_id = meta.get('supplierId')

    sku_list = list()
    js_str = clean_jsonp(response.text)
    if not js_str:
        return sku_list
    rs = json.loads(js_str)
    if 'productList' in rs:
        for row in rs.get('productList'):
            sku = Sku()
            sku_id = base64_decode(row.get('prodId'))
            sku['skuId'] = sku_id
            sku['supplierId'] = sp_id
            sku['salePrice'] = row.get('prodPrice')
            sku['soldCount'] = row.get('saleAmt')
            sku_list.append(sku)

    return sku_list


# 解析ItemData
def parse_item_data(response):
    meta = response.meta
    batch_no = meta.get('batchNo')
    sku_id = meta.get('skuId')

    jpy = PyQuery(response.text)
    supplier = jpy('div.product_top_r li.shop_name p')
    images = jpy('div#preview img#skuImg')
    nav = jpy('div.graybar_wrap div.graybar a')
    price_box = jpy('div.price_box dl')
    external_price_links = jpy('div.external_price_box ul li a')

    # -------------------------------------------------
    result = EsgccItemData()
    result['batchNo'] = batch_no
    result['skuId'] = sku_id
    material_code = jpy('input#materialId')
    if material_code and material_code.attr('value'):
        result['materialCode'] = material_code.attr('value').strip()
    sku_name = jpy('input#prodName_name')
    if sku_name:
        result['skuName'] = jpy('input#prodName_name').attr('value').strip()
    else:
        result['skuName'] = jpy('h1#prodName').text().strip()
    if images:
        result['skuImg'] = images.attr('src').strip()
    # 一级分类
    cat1Name = nav.eq(0).text().strip()
    result['catalog1Name'] = cat1Name
    result['catalog1Id'] = double_base64_encode(cat1Name + ':1')
    # 二级分类
    cat2Name = nav.eq(1).text().strip()
    result['catalog2Name'] = cat2Name
    result['catalog2Id'] = double_base64_encode(cat2Name + ':2')
    # 三级分类
    cat3Name = nav.eq(2).text().strip()
    result['catalog3Id'] = double_base64_encode(cat3Name)
    result['catalog3Name'] = cat3Name
    result['salePrice'] = parse_number(jpy('input#prodPrice').attr("value"))
    org_price = parse_number(jpy('input#prodOriginPrice').attr("value"))
    if org_price:
        result['originPrice'] = org_price
    else:
        result['originPrice'] = parse_number(price_box('dt:contains(价格指数) + dd').text(), 0)
    result['unit'] = jpy('input#materialUnitName').attr('value').strip()
    result['supplierId'] = jpy('input#storeId').attr('value').strip()
    result['supplierName'] = supplier.attr('title').strip()
    ext_links = list()
    if external_price_links:
        for link in external_price_links.items():
            ext_links.append(link.attr('href'))
    result['extLinks'] = ext_links

    # 价格指数
    result['priceIndex'] = parse_number(price_box('dt:contains(价格指数) + dd').text(), 0)
    # 外部均价
    result['outAvgPrice'] = parse_number(price_box('dt:contains(外部均价) + dd').text(), 0)
    # 库存
    result['stock'] = parse_number(jpy('strong.isHaveStock').attr('val'), -999)
    result['genTime'] = datetime.utcnow()
    # -------------------------------------------------

    return result


# 解析order列表页数
def parse_prod_detail(response):
    meta = response.meta
    result = meta.get('data')
    jpy = PyQuery(response.text)
    brand_li = jpy('ul.detail_list li:contains(品牌：)')
    if brand_li and brand_li.attr('title'):
        brand = brand_li.attr('title').strip()
        result['brandId'] = md5(brand)
        result['brandName'] = brand
    brand_model = jpy('ul.detail_list li span:contains(型号规格：) + span')
    if brand_model:
        result['brandModel'] = brand_model.attr('title')
    put_on_li = jpy('ul.detail_list li:contains(上架时间：)')
    if put_on_li:
        put_on_time = put_on_li.text().replace('上架时间：', '').strip()
        result['onSaleTime'] = parse_time(put_on_time)

    return result


# 解析同款商品
def parse_group(response):
    meta = response.meta
    sku_id = meta.get('skuId')
    group = ItemGroup()
    group_list = list()
    compare_list = list()
    done_set = set()
    done_set.add(sku_id)

    js = json.loads(response.text)
    if js and 'compareProd' in js:
        same_list = js.get('compareProd')
        if same_list and len(same_list):
            for same in same_list:
                same_sku_id = same.get('PROD_ID')
                # 同款商品编号
                group_list.append(same_sku_id)
                done_set.add(same_sku_id)
                # 同款商品
                compare = EsgccCompareGroup()
                compare['skuId'] = same.get('PROD_ID')
                compare['totalSaleNum'] = same.get('saleNum')
                compare['deviation'] = get_deviation(same)
                compare['gear'] = same.get('gear')
                compare_list.append(compare)

    # 本商品
    if js and 'deviation' in js:
        group_list.append(sku_id)
        compare = EsgccCompareGroup()
        compare['skuId'] = sku_id
        compare['deviation'] = get_deviation(js)
        compare['gear'] = js.get('gear')
        compare_list.append(compare)
    # 同款（含自身）
    if group_list and len(group_list):
        group['skuId'] = meta.get('skuId')
        group['spuId'] = short_uuid()
        group['skuIdList'] = group_list

    return group, compare_list, done_set


# # 解析order列表页数
# def parse_total_page(response):
#     jpy = PyQuery(response.text)
#
#     return int(jpy('div.page_wrap a.nextPag').prev().text().strip())
#
#
#
# # 解析order列表页数
# def parse_order_total_page_ios(response):
#     total_page = 0
#     order_list = list()
#     rs = _parse_order_response(response)
#     data = rs.get('resultDTO', {}).get('data', {})
#     if data:
#         total_num = data.get('totalNum', 0)
#         page_size = data.get('page', {'pageSize': 10}).get('pageSize', 10)
#         total_page = math.ceil(total_num / page_size)
#         orders = data.get('orders', [])
#         if orders:
#             for order in orders:
#                 order_id = order.get('orderId')
#                 order_dept = order.get('transactionDesc')
#                 order_time = parse_time(order.get('orderPayTimeStr'))
#                 page = Order()
#                 page['id'] = order_id
#                 page['url'] = 'http://buser.esgcc.com.cn/order/recent_purchase_detail?orderId={}'.format(order_id)
#                 page['orderTime'] = order_time
#                 page['orderDept'] = order_dept
#                 page['batchNo'] = time_to_batch_no(order_time)
#                 page['genTime'] = datetime.utcnow()
#                 order_list.append(page)
#
#     return order_list, total_page
#
#
# # 解析order列表
# def parse_order(response):
#     jpy = PyQuery(response.text)
#
#     pages = list()
#     trs = jpy('table.info_open_table tbody tr')
#     if trs and trs.size():
#         for tr in trs.items():
#             tds = tr('td')
#             if tds and tds.size():
#                 order_time = parse_time(tds.eq(1).text()[0:8] + '180000', fmt='%Y%m%d%H%M%S')
#                 order_dept = tds.eq(3).text()
#                 supplier_name = tds.eq(5).text()
#                 page = dict()
#                 page['id'] = tds.eq(1).text()
#                 page['url'] = 'http://buser.esgcc.com.cn/order/recent_purchase_detail?orderId={}'.format(tds.eq(1).text())
#                 page['orderTime'] = order_time
#                 page['orderDept'] = order_dept
#                 if supplier_name:
#                     page['supplierName'] = supplier_name
#                 # page['orderUser'] = tds.eq(3).text().strip()
#                 page['batchNo'] = time_to_batch_no(order_time)
#                 page['genTime'] = datetime.utcnow()
#                 pages.append(page)
#
#     return pages
#
#
# # 解析order列表
# def parse_order_list_home(response):
#     order_list = list()
#     rows = json.loads(response.text)
#     for row in rows:
#         order_time = parse_time(row.get('ORDER_PAY_TIME_STR'))
#         total_price = parse_number(row.get('ORDER_MONEY'))
#
#         order = Order()
#         order['id'] = row.get('ORDER_ID')
#         order['orderDept'] = row.get('TRANSACTION_DESC')
#         order['supplierName'] = row.get('STORE_NAME', '')
#         order['orderUser'] = row.get('LOGIN_ACCOUNT', '')
#         order['totalPrice'] = total_price
#         order['orderTime'] = order_time
#         order['batchNo'] = time_to_batch_no(order_time)
#         order['genTime'] = datetime.utcnow()
#         order_list.append(order)
#
#     return order_list


# 解析sku列表
def parse_order_item(response):
    jpy = PyQuery(response.text)

    meta = response.meta
    supplier_name = meta.get('supplierName', None)
    order_id = meta.get('orderId')
    order_time = meta.get('orderTime')
    order_dept = meta.get('orderDept')

    orders = list()
    ul_list = jpy('div.goods_warp div.goods_info ul')
    if order_dept and len(ul_list):
        for idx, ul in enumerate(ul_list.items()):
            lis = ul('li')
            sku_url = lis.eq(1)('a').eq(0).attr('href').strip()
            order = OrderItem()
            order['id'] = order_id + '_' + str(idx)
            order['orderId'] = order_id
            order['skuId'] = str(match_sku_id(sku_url))
            # 此平台中数量可能存在小数，四舍五入兼容处理
            order['count'] = round(parse_number(lis.eq(3).text().strip()))
            order['amount'] = parse_number(lis.eq(2).text().strip())
            if supplier_name:
                order['supplierName'] = supplier_name
            order['orderDept'] = order_dept
            order['orderTime'] = order_time
            order['batchNo'] = time_to_batch_no(order_time)
            order['genTime'] = datetime.utcnow()
            orders.append(order)
    else:
        logger.info('异常订单[%s]', order_id)

    return orders


def _parse_ios_order_response(response):
    ex_data = json.loads(response.text).get('exData', '').replace('\n', '')
    str_decode = base64_decode(base64_decode(ex_data))
    return json.loads(str_decode)


# 解析order列表页数
def parse_order_item_ios(response):
    meta = response.meta
    order_id = meta.get('orderId')
    order_time = meta.get('orderTime', '')

    order_list = list()
    rs = _parse_ios_order_response(response)
    data = rs.get('resultDTO', {}).get('data', {})
    if data:
        items = data.get('orderFlows', {}).get('items', [])
        if items:
            flow_time = items[len(items) - 1].get('operate_time', {}).get('time', '')
            order_time = parse_timestamp(flow_time)
        if not order_time:
            order_time = parse_time(order_id[0:8] + '180000', fmt='%Y%m%d%H%M%S')

        orders = data.get('orderProdList', [])
        if orders:
            for idx, order in enumerate(orders):
                sp_name = order.get('store_name')

                item = OrderItem()
                item['id'] = order_id + '_' + str(idx)
                item['orderId'] = order_id
                item['skuId'] = str(order.get('prod_id'))
                # 此平台中数量可能存在小数，四舍五入兼容处理
                item['count'] = round(order.get('prod_buy_amt'))
                item['amount'] = order.get('prod_totel_amt')
                if not item['amount']:
                    item['amount'] = order.get('prod_totel_amt_act')
                if not item['amount']:
                    item['amount'] = order.get('paybackThreshold')
                if sp_name:
                    item['supplierName'] = order.get('store_name', '')

                item['orderDept'] = order.get('invoice_title')
                item['deptId'] = md5(order.get('invoice_title'))
                item['orderAddr'] = order.get('consignee_address_detail', '')
                item['orderUser'] = order.get('user_name', '')
                item['userAcct'] = order.get('login_account', '')
                item['orderTel'] = order.get('consignee_mobile', '')
                item['orderTime'] = order_time
                item['batchNo'] = time_to_batch_no(order_time)
                item['genTime'] = datetime.utcnow()

                order_list.append(item)

    return order_list, order_time


# -------------------------
# 解析商品属性
def parse_attr(response):
    attr_list = list()
    meta = response.meta
    batch_no = meta.get('batchNo')

    sku_attr = SkuAttr()
    sku_attr['batchNo'] = batch_no
    sku_attr['skuId'] = meta.get('skuId')
    sku_attr['attrList'] = attr_list
    jpy = PyQuery(response.text)
    group_list = jpy('div.pList div.t_tit')
    for grp in group_list.items():
        group_name = grp.text()
        kv_list = grp.next('ul')('li')
        for kv in kv_list.items():
            key = kv('div.p_tit').text()
            val = kv('div.p_parameter').text()

            attr = dict()
            attr['group'] = group_name
            attr['key'] = key
            attr['val'] = val
            attr_list.append(attr)

    return sku_attr